import { useCallback, useState, forwardRef, ReactElement, MutableRefObject } from 'react';
import { SearchEngineProps } from '../preview/web';
import { SearchPropsContext, StateType } from './searchPropsContext';
import { SearchUIContext, SearchUIStateType } from './searchUIContext';
export const SearchPropsProvider = forwardRef(
  (
    props: StateType & {
      children: ReactElement;
      configEvents: MutableRefObject<SearchEngineProps['callBackEvents']>;
    },
    ref: any
  ) => {
    const [uiState, setUIState] = useState<SearchUIStateType>({
      selectShowTab: undefined,
      ecmSearchType: undefined,
      keyword: '',
      switchAdSearch: false,
      isFuzzySearch: true,
      showSearchResultPanel: false,
      panelId: '',
      searchFolder: 'allFolder',
      keywords: [],
      nowText: undefined,
      showGraph: false,
      searchBtnWidth: 150,
      fullScreen: false,
      showFullModal: false,
      historyDataLength: 0,
      quickDataLength: 0,
      showTag: true,
      showTeam: true,
      showPerson: true,
      visibleDrawer: false,
    });

    const updateUIState = useCallback((newState: Partial<SearchUIStateType>) => {
      setUIState((prev) => {
        return {
          ...prev,
          ...newState,
        };
      });
    }, []);

    const configEventsApi = useCallback(
      async <T extends (...params: any) => Promise<any>>({
        request,
        params,
        keys: [onParams, onRequest, onData],
      }: {
        request: T;
        params: Parameters<T>[0];
        keys: string[];
        //@ts-ignore
      }): ReturnType<T> => {
        const newParams = (await props.configEvents.current?.[onParams!]?.(params)) || params;
        const data = await (props.configEvents.current?.[onRequest] || request)(newParams);
        return (await props.configEvents.current?.[onData]?.(data, newParams)) || data;
      },
      [props.configEvents],
    );

    return (
      <SearchPropsContext.Provider
        value={{ state: props, configEventsApi, configEvents: props.configEvents }}
      >
        <SearchUIContext.Provider value={{ state: uiState, updateUIState }}>
          {props.children}
        </SearchUIContext.Provider>
      </SearchPropsContext.Provider>
    );
  },
);
